﻿using System;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using TS3QueryLib.Core.CommandHandling;

namespace TS3QueryLib.Tests.CommandHandling
{
    [TestClass]
    public class CommandParameterGroupListTest
    {
        [TestMethod]
        public void TestOnlyParameterNameInSingleGroup()
        {
            Assert.AreEqual(@"secretpassword secret\ppassword", new CommandParameterGroupList {  new CommandParameterGroup { new CommandParameter("secretpassword"), new CommandParameter("secret|password") }}.ToString());
        }

        [TestMethod]
        public void TestParameterNameAndValueInSingleGroup()
        {
            Assert.AreEqual(@"key=value key=val\pue key=val\sue", new CommandParameterGroupList { new CommandParameterGroup { new CommandParameter("key", "value"), new CommandParameter("key", "val|ue"), new CommandParameter(" key ", " val ue ") } }.ToString());
        }

        [TestMethod]
        public void TestParameterNameAndValueInMultipleGroups()
        {
            Assert.AreEqual
            (
                @"key1=value1|key2=value2 key2=val\pue2 key2=val\sue2|key3=value3 key3=val\pue3 key3=val\sue3|key4=value4 key4=val\sue4", 
                new CommandParameterGroupList
                {
                    new CommandParameterGroup { new CommandParameter("key1", "value1")},
                    new CommandParameterGroup { new CommandParameter("key2", "value2"), new CommandParameter("key2", "val|ue2"), new CommandParameter(" key2 ", " val ue2 ") },
                    new CommandParameterGroup { new CommandParameter("key3", "value3"), new CommandParameter("key3", "val|ue3"), new CommandParameter(" key3 ", " val ue3 ") },
                    new CommandParameterGroup { new CommandParameter("key4", "value4"), new CommandParameter(" key4 ", " val ue4 ") }
                }.ToString()
            );
        }

        [TestMethod]
        public void TestParseEmptyString()
        {
            CommandParameterGroupList list;
            
            list = CommandParameterGroupList.Parse(null);
            Assert.IsNotNull(list);
            Assert.AreEqual(0, list.Count);

            list = CommandParameterGroupList.Parse(string.Empty);
            Assert.IsNotNull(list);
            Assert.AreEqual(0, list.Count);

            list = CommandParameterGroupList.Parse("        ");
            Assert.IsNotNull(list);
            Assert.AreEqual(0, list.Count);
        }

        [TestMethod]
        public void TestParseSingleGroup()
        {
            CommandParameterGroupList list;
            CommandParameter parameter;

            list = CommandParameterGroupList.Parse(@"secretpassword");
            Assert.AreEqual(1, list.Count);

            parameter = list.GetParameter("secretpassword");
            Assert.IsNotNull(parameter);
            Assert.IsNull(parameter.Value);


            list = CommandParameterGroupList.Parse(@"secret\ppassword");
            Assert.AreEqual(1, list.Count);

            parameter = list.GetParameter("secret|password");
            Assert.IsNotNull(parameter);
            Assert.IsNull(parameter.Value);


            list = CommandParameterGroupList.Parse(@"secretpassword secret\ppassword");
            Assert.AreEqual(1, list.Count);

            parameter = list.GetParameter("secretpassword");
            Assert.IsNotNull(parameter);
            Assert.IsNull(parameter.Value);

            
            parameter = list.GetParameter("secret|password");
            Assert.IsNotNull(parameter);
            Assert.IsNull(parameter.Value);


            list = CommandParameterGroupList.Parse(@"password=secret\ppassword");
            Assert.AreEqual(1, list.Count);

            parameter = list.GetParameter("password");
            Assert.IsNotNull(parameter);
            Assert.AreEqual("secret|password", parameter.Value);


            list = CommandParameterGroupList.Parse(@"user=scordo password=secret\ppassword");
            Assert.AreEqual(1, list.Count);

            parameter = list.GetParameter("user");
            Assert.IsNotNull(parameter);
            Assert.AreEqual("scordo", parameter.Value);

            parameter = list.GetParameter("password");
            Assert.IsNotNull(parameter);
            Assert.AreEqual("secret|password", parameter.Value);

            list = CommandParameterGroupList.Parse(@"user=scordo single\pone password=secret\ppassword");
            Assert.AreEqual(1, list.Count);

            parameter = list.GetParameter("user");
            Assert.IsNotNull(parameter);
            Assert.AreEqual("scordo", parameter.Value);

            parameter = list.GetParameter("single|one");
            Assert.IsNotNull(parameter);
            Assert.IsNull(parameter.Value);

            parameter = list.GetParameter("password");
            Assert.IsNotNull(parameter);
            Assert.AreEqual("secret|password", parameter.Value);


            list = CommandParameterGroupList.Parse(@"user=scordo single\pone emptyvalue= password=secret\ppassword");
            Assert.AreEqual(1, list.Count);

            parameter = list.GetParameter("user");
            Assert.IsNotNull(parameter);
            Assert.AreEqual("scordo", parameter.Value);

            parameter = list.GetParameter("single|one");
            Assert.IsNotNull(parameter);
            Assert.IsNull(parameter.Value);

            parameter = list.GetParameter("emptyvalue");
            Assert.IsNotNull(parameter);
            Assert.AreEqual(parameter.Value, String.Empty);

            parameter = list.GetParameter("password");
            Assert.IsNotNull(parameter);
            Assert.AreEqual("secret|password", parameter.Value);


            list = CommandParameterGroupList.Parse(@"user=scordo single\pone emptyvalue= hash=hsdhjsd= password=secret\ppassword");
            Assert.AreEqual(1, list.Count);

            parameter = list.GetParameter("user");
            Assert.IsNotNull(parameter);
            Assert.AreEqual("scordo", parameter.Value);

            parameter = list.GetParameter("single|one");
            Assert.IsNotNull(parameter);
            Assert.IsNull(parameter.Value);

            parameter = list.GetParameter("emptyvalue");
            Assert.IsNotNull(parameter);
            Assert.AreEqual(parameter.Value, String.Empty);

            parameter = list.GetParameter("hash");
            Assert.IsNotNull(parameter);
            Assert.AreEqual(parameter.Value, "hsdhjsd=");

            parameter = list.GetParameter("password");
            Assert.IsNotNull(parameter);
            Assert.AreEqual("secret|password", parameter.Value);
        }

        [TestMethod]
        public void TestParseMultipleGroups()
        {
            CommandParameter parameter;

            CommandParameterGroupList list = CommandParameterGroupList.Parse(@"cid=2 cldbid=9 cgid=9|cid=2 cldbid=24 cgid=9|cid=2 cldbid=47 cgid=9");
            Assert.AreEqual(3, list.Count);

            parameter = list.GetParameter("cid");
            Assert.IsNotNull(parameter);
            Assert.AreEqual("2", parameter.Value);

            parameter = list.GetParameter("cldbid");
            Assert.IsNotNull(parameter);
            Assert.AreEqual("9", parameter.Value);

            parameter = list.GetParameter("cgid");
            Assert.IsNotNull(parameter);
            Assert.AreEqual("9", parameter.Value);


            parameter = list.GetParameter("cid", 1);
            Assert.IsNotNull(parameter);
            Assert.AreEqual("2", parameter.Value);

            parameter = list.GetParameter("cldbid", 1);
            Assert.IsNotNull(parameter);
            Assert.AreEqual("24", parameter.Value);

            parameter = list.GetParameter("cgid", 1);
            Assert.IsNotNull(parameter);
            Assert.AreEqual("9", parameter.Value);


            parameter = list.GetParameter("cid", 2);
            Assert.IsNotNull(parameter);
            Assert.AreEqual("2", parameter.Value);

            parameter = list.GetParameter("cldbid", 2);
            Assert.IsNotNull(parameter);
            Assert.AreEqual("47", parameter.Value);

            parameter = list.GetParameter("cgid", 2);
            Assert.IsNotNull(parameter);
            Assert.AreEqual("9", parameter.Value);
        }
    }
}